import logging
import asyncio
import zlib
import json
import telnetlib3
from telnetlib3.telopt import CHARSET, GMCP
import re
from collections import deque

# 定义MSSP和MSP协议选项代码
MSSP = b'F'  # 70
MSP = b'Z'   # 90
# MCCP2压缩协议选项代码
MCCP2 = b'V'  # 86

# MSSP协议中的特殊字节
MSSP_VAR = b'\x01'  # 变量名开始
MSSP_VAL = b'\x02'  # 变量值开始

class ExtensionWriter():
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 初始化MCCP2相关属性
        self.mccp2_compressing = True  # 始终启用压缩处理
        self.decompressor = zlib.decompressobj(-15)  # 使用原始deflate算法
        self.compressed_buffer = bytearray()  # 压缩数据缓冲区
    
    def handle_will(self, option):
        """
        重写handle_will方法，拦截CHARSET、GMCP、MSSP、MCCP2和MSP协商
        
        Args:
            option (bytes): 选项代码
        """

        # 特别处理CHARSET、GMCP、MSSP和MSP选项
        if option in (CHARSET, GMCP, MSSP, MSP):
            option_name = {CHARSET: "CHARSET", GMCP: "GMCP", MSSP: "MSSP", MSP: "MSP"}.get(option, "UNKNOWN")
            self.log.debug(f"{option_name}协议请求，客户端接受并发送DO响应")
            self.iac(telnetlib3.DO, option)
            return True
        elif option == MCCP2:
            # 发送DO，同意MCCP2协商
            self.log.debug("服务器请求启用MCCP2协议，客户端同意")
            self.iac(telnetlib3.DO, option)
            return True
        
        # 对于其他选项，调用父类方法处理
        return super().handle_will(option)

    def handle_do(self, option):
        """
        重写handle_do方法，拦截MSSP、MSP和MCCP2协商
        
        Args:
            option (bytes): 选项代码
        """
        # 特别处理MSSP、MSP和MCCP2选项 - 统一发送WILL响应
        if option in (MSSP, MSP, MCCP2):
            option_name = {MSSP: "MSSP", MSP: "MSP", MCCP2: "MCCP2"}.get(option, "UNKNOWN")
            self.log.debug(f"服务器请求启用{option_name}协议，客户端发送WILL响应")
            self.iac(telnetlib3.WILL, option)
            return True
            
        # 对于其他选项，调用父类方法处理
        return super().handle_do(option)

    def handle_subnegotiation(self, buf):
        """
        重写handle_subnegotiation方法，添加对MSSP子协商的支持
        
        Args:
            buf (collections.deque): 子协商数据缓冲区
        """
        if not buf:
            raise ValueError("SE: buffer empty")
        if buf[0] == telnetlib3.theNULL:
            raise ValueError("SE: buffer is NUL")
        # 修复：允许长度为1的缓冲区（MCCP2子协商开始）
        if len(buf) < 1:
            raise ValueError("SE: buffer too short: {!r}".format(buf))

        cmd = buf[0]
        if self.pending_option.enabled(telnetlib3.SB + cmd):
            self.pending_option[telnetlib3.SB + cmd] = False
        else:
            self.log.debug("[SB + {}] unsolicited ext".format(telnetlib3.name_command(cmd)))

        # 处理MSSP子协商
        if cmd == MSSP:
            self._handle_sb_mssp(buf)
            return
        elif cmd == MSP:
            self._handle_sb_msp(buf)
            return
        elif cmd == MCCP2:
            self._handle_sb_mccp2(buf)
            return
            
        # 对于其他选项，调用父类方法处理
        super().handle_subnegotiation(buf)

    def handle_ga(self, cmd):
        """Handle IAC Go-Ahead (GA)."""
        self.log.debug("收到GA信号，可以推送消息")


    def _handle_sb_mccp2(self, buf):
        """
        处理MCCP子协商数据
        
        Args:
            buf (collections.deque): MCCP数据包
        """
        # 只需记录日志，实际的压缩处理在feed_byte中进行
        self.log.debug("MCCP2压缩已启用")


    def _handle_sb_mssp(self, buf):
        """
        处理MSSP子协商数据
        
        Args:
            buf (collections.deque): MSSP数据包
        """
        self.log.debug(f"收到MSSP子协商数据: {list(buf)}")
        
        # 解析MSSP数据
        # MSSP格式: MSSP_VAR KEY MSSP_VAL VALUE MSSP_VAR KEY MSSP_VAL VALUE ...
        buf_copy = list(buf)[1:]  # 移除第一个字节(MSSP选项)
        
        mssp_data = {}
        current_key = None
        current_value = []
        is_key = False
        is_value = False
        
        i = 0
        while i < len(buf_copy):
            byte = buf_copy[i]
            
            if byte == MSSP_VAR:
                # 新的键开始
                if current_key is not None and current_value:
                    # 保存之前的键值对
                    key_str = b''.join(current_value).decode('utf-8', errors='ignore')
                    mssp_data[current_key] = key_str
                
                current_key = None
                current_value = []
                is_key = True
                is_value = False
            elif byte == MSSP_VAL:
                # 值开始
                if current_key is None and current_value:
                    # 保存键
                    current_key = b''.join(current_value).decode('utf-8', errors='ignore')
                
                current_value = []
                is_key = False
                is_value = True
            else:
                # 数据字节
                current_value.append(byte)
            
            i += 1
        
        # 保存最后一个键值对
        if current_key is not None and current_value:
            value_str = b''.join(current_value).decode('utf-8', errors='ignore')
            mssp_data[current_key] = value_str
        
        self.log.debug(f"MSSP数据解析完成: {mssp_data}")

    def _handle_sb_msp(self, buf):
        """
        处理MSP子协商数据
        
        Args:
            buf (collections.deque): MSP数据包
        """
        self.log.debug(f"收到MSP子协商数据: {list(buf)}")

    def _handle_sb_gmcp(self, buf):
        """
        处理GMCP子协商数据
        
        Args:
            buf (list): GMCP数据包
        """
        try:
            gmcp_data = b''.join(buf)
            self.log.debug(f"收到GMCP数据: {gmcp_data}")
            
            # 解析GMCP数据
            gmcp_str = gmcp_data.decode('utf-8', errors='ignore')
            
            # 使用正则表达式分离包名和JSON数据
            match = re.match(r'^([^ ]+) (.*)$', gmcp_str)
            if match:
                package_name = match.group(1)
                json_data = match.group(2)
                
                self.log.debug(f"GMCP包名: {package_name}")
                self.log.debug(f"GMCP数据: {json_data}")
                
                # 解析JSON数据
                try:
                    data = json.loads(json_data)
                    self.log.debug(f"解析后的GMCP数据: {data}")
                    
                    # 根据包名处理不同类型的数据
                    if package_name == "GMCP.Move":
                        self._handle_move_data(data)
                    # 可以添加更多包类型的处理
                except json.JSONDecodeError as e:
                    self.log.error(f"GMCP JSON解析错误: {e}")
            else:
                self.log.warning(f"无法解析GMCP格式: {gmcp_str}")
                
        except Exception as e:
            self.log.error(f"处理GMCP数据时出错: {e}")

    def _handle_move_data(self, data):
        """
        处理GMCP.Move数据
        
        Args:
            data (dict): 解析后的移动数据
        """
        self.log.debug(f"处理移动数据: {data}")
        # 在这里可以添加具体的移动数据处理逻辑
        # 例如更新用户界面显示当前位置、可行走的方向等


class MUDTelnetWriter(ExtensionWriter, telnetlib3.TelnetWriter):
    """
    MUD客户端的Telnet写入器无编码类
    继承TelnetWriter外壳，主要实现依赖ExtensionWriter
    """
    def __init__(self, *args, **kwargs):
        # 初始化父类
        super().__init__(*args, **kwargs)



class MUDTelnetWriterUnicode(ExtensionWriter, telnetlib3.TelnetWriterUnicode):
    """
    MUD客户端的Telnet写入器Unicode类
    继承TelnetWriterUnicode外壳，主要实现依赖ExtensionWriter
    """
    def __init__(self, *args, **kwargs):
        # 初始化父类
        super().__init__(*args, **kwargs)

